<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8" />
		<title></title>
		<link rel="stylesheet" type="text/css" href="css/styles.css" />
		<style type="text/css">
			html,
			body {
				width: 100%;
				height: 100%;
			}
			
			.wrapper {
				background: #eee;
				padding-top: 1rem;
				padding-bottom: 1rem;
				position: relative;
			}
			
			.wrapper.hide {
				overflow-x: hidden;
				height: 100%;
				box-sizing: border-box;
			}
			
			.wrapper .item {
				box-sizing: border-box;
				width: 100%;
				max-height: 1000px;
				padding: 1rem;
				background: white;
				margin-bottom: 1rem;
				border: .1rem solid #d0cfcf;
				overflow: hidden;
				transition: height .8s, max-height .8s, opacity .8s;
				/*transition-timing-function: ease;*/
			}
			
			.wrapper .item.hide {
				height: 0;
				max-height: 0;
				opacity: 0;
				/*overflow: hidden;*/
				display: none;
			}
			
			.wrapper .item:nth-child(1) {
				margin-top: 0;
			}
			
			.wrapper .item:last-child {
				margin-bottom: 0;
			}
			
			.wrapper .item .content {
				max-height: 1000px;
				/* background: lightblue; */
			}
			
			.wrapper .item:not(.turnSmall) .content {
				transition: .8s linear;
			}
			
			.wrapper.hide .item .content {
				max-height: 0;
				overflow: hidden;
			}
			
			.wrapper .item .content p {
				line-height: 6rem;
				font-size: 6rem;
				text-align: center;
				-webkit-user-select: none;
			}
			
			.turnSmall {
				position: absolute;
			}
			
			.blueline {
				/*border: .1rem solid blue;*/
				border: 1rem solid rgba(255, 255, 255, 0);
				margin: .2rem 0;
				/*background: blue;*/
			}
			
			.blueline.hide {
				display: none;
			}
			
			.temp-wrapper {
				display: none;
			}
			
			.banner {
				width: 100%;
				/* background: gray; */
				/* background: lightblue; */
			}
			
			.banner p {
				/* line-height: 10rem; */
				/* font-size: 6rem; */
				/* text-align: center; */
				padding: 1rem;
				font-weight: 600;
				/* color: white; */

				/*color: white;*/
				/* text-shadow: 0 0 1rem rgba(255, 255, 255, 1); */
			}
			
			.outer-wrapper.active {
				width: 100%;
				height: 100%;
				position: fixed;
				z-index: 100;
				top: 0;
				left: 0;
			}
		</style>
	</head>

	<body>
		<div class="banner">
			<p>移动端长按拖动列表</p>
		</div>
		<div class="outer-wrapper">
			<div class="wrapper">
				<hr class="blueline hide" />
			</div>
		</div>

		<div class="temp-wrapper">
			<div class="item item1" data-seq="1">
				<p>可拖动item1</p>
				<div class="content">
					<p>1</p>
				</div>
			</div>
			<div class="item item2" data-seq="2">
				<p>可拖动item2</p>
				<div class="content">
					<p>2</p>
				</div>
			</div>
			<div class="item item3" data-seq="3">
				<p>可拖动item3</p>
				<div class="content" >
					<p>3</p>
				</div>
			</div>
			<div class="item item4" data-seq="4">
				<p>可拖动item4</p>
				<div class="content">
					<p>4</p>
				</div>
			</div>
			<div class="item item5" data-seq="5">
				<p>可拖动item5</p>
				<div class="content">
					<p>5</p>
				</div>
			</div>
			<div class="item item6" data-seq="6">
				<p>可拖动item6</p>
				<div class="content">
					<p>6</p>
				</div>
			</div>
		</div>
		<script src="js/jquery-1.11.1.min.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			//响应排列顺序
			var seqConfig = {
				1: "item1",
				2: "item2",
				3: "item3",
				4: "item4",
				5: "item5",
				6: "item6"
			};

			var cacheSeq = localStorage.getItem("cacheSeq");
			if(cacheSeq) {
				var seqArr = cacheSeq.split(",");
				for(var i = 0; i < seqArr.length; i++) {
					$(".wrapper").append($(".temp-wrapper ." + seqConfig[seqArr[i]]));
				}
			} else {
				for(var i = 0; i < 6; i++) {
					$(".wrapper").append($(".temp-wrapper ." + seqConfig[i + 1]));
				}
			}

			//移动事件
			var timeout;
			var time_touchstart = 0;
			var moving = false;
			var itemHiding = false;
			var touchstart_scaling = false;

			$(".wrapper").delegate(".item", "touchstart", function(ev) {
				ev.preventDefault();
				//mac chrome 调试用
				//ev.preventDefault();

				_this = this;

				if($(".turnSmall").length > 0) {
					return;
				} else {
					var touch = ev.originalEvent.targetTouches[0];
					time_touchstart = new Date().getMilliseconds();
					timeout = setTimeout(function() {
						moving = true;
						//防止，缩小时误隐藏
						touchstart_scaling = true;
						$(".outer-wrapper").addClass("active");
						$(".blueline").removeClass("hide");
						$(".wrapper").addClass("hide");
						$(_this).addClass("turnSmall");
						$(".wrapper").addClass("hide");
						$(_this).addClass("turnSmall");
						$(".turnSmall")
							.css("left", touch.pageX - $(".wrapper").offset().left)
							.css("top", touch.pageY - $(".wrapper").offset().top);

						var clientY = touch.clientY;
						setTimeout(function() {
							touchstart_scaling = false;
							var windowScroll = window.scrollY || window.pageYOffset;
							var wrapperOffsetY = $(".wrapper").offset().top;
							if(windowScroll < wrapperOffsetY) {
								$(".turnSmall").css("top", clientY - (wrapperOffsetY - windowScroll));
							} else {
								$(".turnSmall").css("top", clientY + (wrapperOffsetY - windowScroll));
							}
						}, 1000);
					}, 1000);
				}
			});

			$(".wrapper").delegate(".item", "touchmove", function(ev) {
				ev.preventDefault();
				if(moving) {
					ev.preventDefault();
					ev.stopPropagation();
					var touch = ev.originalEvent.targetTouches[0];
					var item_move = $(".turnSmall");
					item_move
						.css("left", touch.pageX - $(".wrapper").offset().left)
						.css("top", touch.pageY - $(".wrapper").offset().top);
					//不动的item
					var static_items = $(".item:not(.turnSmall):not(.hide)");

					var clientH = static_items.eq(0).height();
					var top = touch.pageY - $(".wrapper").offset().top;
					//超后
					if(top > static_items.eq(static_items.length - 1).position().top + clientH) {
						static_items.eq(static_items.length - 1).after($(".blueline"));
					}
					//超前
					else if(top < static_items.eq(0).position().top) {
						static_items.eq(0).before($(".blueline"));
					} else {
						for(var i = 0; i < static_items.length; i++) {
							var item_s_top = static_items.eq(i).position().top;
							if(top > item_s_top && top < item_s_top + clientH) {
								if(top > item_s_top + clientH / 2) {
									static_items.eq(i).after($(".blueline"));
								} else {
									static_items.eq(i).before($(".blueline"));
								}
							}
						}
					}

					//标线在可视区
					var hrOffsetY = $(".blueline").offset().top;
					var hrHeight = $(".blueline").get(0).offsetHeight;
					var windowScroll = window.scrollY || window.pageYOffset;
					if(!touchstart_scaling && !itemHiding) {
						if(hrOffsetY < $(".item:not(.turnSmall):not(.hide)").eq(0).offset().top) {
							$(".item.hide").eq($(".item.hide").length - 1).removeClass("hide");
							itemHiding = true;
							setTimeout(function() {
								itemHiding = false;
							}, 1500);
						} else if(((windowScroll + window.innerHeight - hrOffsetY - hrHeight < clientH) && (static_items.eq(static_items.length - 1).offset().top + clientH > windowScroll + window.innerHeight)) ||
							windowScroll + window.innerHeight < hrOffsetY + hrHeight) {
							$(".item:not(.turnSmall):not(.hide)").eq(0).addClass("hide");
							itemHiding = true;
							setTimeout(function() {
								itemHiding = false;
							}, 1500);
						}
					}
				}
			});

			$(".wrapper").delegate(".turnSmall", "touchend", function(ev) {
				ev.preventDefault();
				var _this = this;
				$(".blueline").after($(_this));
				$(_this).removeClass("turnSmall");
				$(".wrapper").removeClass("hide");
				$(".item").removeClass("hide");
				moving = false;
				$(".blueline").addClass("hide");
				$(".outer-wrapper").removeClass("active");
				//存储顺序
				//枚举比较好
				var items = $(".item");
				var seq = "";
				for(var i = 0; i < items.length; i++) {
					seq += items.eq(i).attr("data-seq") + ",";
				}
				localStorage.setItem("cacheSeq", seq);

				//				//scrollto
				//				setTimeout(function(){
				//					_this.scrollIntoView();
				//				},500);
			});

			$(".wrapper").delegate(".item", "touchend", function(ev) {
				ev.preventDefault();
				var now = new Date().getMilliseconds();
				if(now - time_touchstart < 1000) {
					clearTimeout(timeout);
				}
			});
		</script>
	</body>

</html>
